use axum::Json;
use serde_json::Value;
use crate::{code, query};

pub fn auto_body_i32<F1: Fn(i32), F2: Fn(Vec<i32>)>(body: &Value, field:&str, one:F1, many:F2) -> Result<(), Json<Value>>{
    let field = if field.is_empty() { "id" } else { field };
    if let Some(f) = query::i32_op(body,field)? {
       one(f);
       Ok(())
    }else{
        if let Some(f) = query::vec_i32_arr_op(&body, field)? {
            many(f);
            Ok(())
        }else{
            Err(code::err_("传递参数不正确"))
        }
    }
}
pub fn auto_body_str<F1: Fn(&str), F2: Fn(Vec<String>)>(body: &Value, field:&str, one:F1, many:F2) -> Result<(), Json<Value>>{
    let field = if field.is_empty() { "id" } else { field };
    if let Some(f) = query::str_op(body,field)? {
       one(&f);
       Ok(())
    }else{
        if let Some(f) = query::vec_str_arr_op(&body, field)? {
            many(f);
            Ok(())
        }else{
            Err(code::err_("传递参数不正确"))
        }
    }
}

pub fn auto_path_i32<F1: Fn(i32)->Result<Json<Value>, Json<Value>>, F2: Fn(Vec<i32>) -> Result<Json<Value>, Json<Value>>>(id:&str, one:F1, many:F2) -> Result<Json<Value>, Json<Value>>{
    if id.contains(",") {
        let f = query::utils::vec_i32_str_(id, "")?;
        many(f)
    }else{
        match id.parse::<i32>() {
            Ok(f) => {
                one(f)
            },
            Err(_)  => Err(code::err_("参数必须是字符串数字"))
        }
    }
}

pub async fn auto_path_str<F1, F2>(id:&str, one:F1, many:F2) -> Result<Json<Value>, Json<Value>> where 
F1: Fn(&str) -> Result<Json<Value>, Json<Value>>,
F2: Fn(Vec<String>) -> Result<Json<Value>, Json<Value>>
{
    if id.contains(",") {
        let f = query::utils::vec_str_str_(id, "")?;
        many(f)
    }else{
        if !id.is_empty() {
            one(id)
        }else{
            Err(code::err_("必选参数必传"))
        }
    }
}

